package com.swensen.game.data;

import java.awt.image.BufferedImage;
import java.io.Serializable;

import com.swensen.game.data.Tile.TileId;

/**
 * The Class Tile.
 */
public abstract class Tile implements Serializable, Comparable<Tile> {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 8552542043884280445L;

	public static class TileId implements Serializable, Comparable<TileId> {
		/**
		 * 
		 */
		private static final long serialVersionUID = 8905129219997689009L;
		private int tileNumber;
		private String fileName;
		
		public TileId(String fileName, int tileNumber) {
			this.tileNumber = tileNumber;
			this.fileName = fileName;
		}
		
		public int getTileNumber() {
			return tileNumber;
		}
		
		public String getFileName() {
			return fileName;
		}

		@Override
		public int hashCode() {
			final int prime = 31;
			int result = 1;
			result = prime * result
					+ ((fileName == null) ? 0 : fileName.hashCode());
			result = prime * result + tileNumber;
			return result;
		}

		@Override
		public boolean equals(Object obj) {
			if (this == obj)
				return true;
			if (obj == null)
				return false;
			if (getClass() != obj.getClass())
				return false;
			TileId other = (TileId) obj;
			if (fileName == null) {
				if (other.fileName != null)
					return false;
			} else if (!fileName.equals(other.fileName))
				return false;
			if (tileNumber != other.tileNumber)
				return false;
			return true;
		}

		@Override
		public int compareTo(TileId o) {
			int res = fileName.compareTo(o.fileName);
			return res != 0 ? res : tileNumber - o.tileNumber;
		}
	}
	
	protected TileId id;
	private TileId originalId;
	
	/**
	 * The Enum TileType.
	 */
	public enum TileType {
		/** The basic. */
		BASIC("til"),
		
		/** The animated. */
		ANIMATED("anm"),
		
		/** The fill. */
		FILL("fll");
		
		/** The extension. */
		private String extension;
		
		/**
		 * Instantiates a new tile type.
		 *
		 * @param extension the extension
		 */
		TileType(String extension) {
			this.extension = extension;
		}

		/**
		 * Gets the extension.
		 *
		 * @return the extension
		 */
		public Object getExtension() {
			return extension;
		}
	}
	
	/** The Constant TILE_SIZE. */
	public static final int TILE_SIZE = 32;
	
	/** The type. */
	private TileType type;
	
	/**
	 * Instantiates a new tile.
	 *
	 * @param type the type
	 */
	public Tile(TileId id, TileType type) {
		this.id = id;
		this.originalId = id;
		this.type = type;
	}

	/**
	 * Gets the image.
	 *
	 * @return the image
	 */
	public abstract TileId getImageData();
	
	/**
	 * Gets the type.
	 *
	 * @return the type
	 */
	public TileType getType() {
		return type;
	}

	public abstract TileId getStillImageData();

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		result = prime * result
				+ ((originalId == null) ? 0 : originalId.hashCode());
		result = prime * result + ((type == null) ? 0 : type.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Tile other = (Tile) obj;
		if (type != other.type)
			return false;
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		if (originalId == null) {
			if (other.originalId != null)
				return false;
		} else if (!originalId.equals(other.originalId))
			return false;
		return true;
	}
	
	@Override
	public int compareTo(Tile t) {
		int res = type.compareTo(t.type);
		if (res != 0) {
			return res;
		}
		
		return id.compareTo(t.id);
	}
	
	public abstract Tile copy();

}
